package com.alibaba.citrus.cr.mn.order.center.facade.function.common;

import com.alibaba.citrus.cr.b2b.trade.order.repository.OrderLineWriteRepository;
import com.alibaba.citrus.cr.b2b.trade.order.repository.OrderQueryServiceRepository;
import com.alibaba.citrus.cr.b2b.trade.order.repository.OrderWriteRepository;
import com.alibaba.citrus.cr.common.annotation.EpochTransactional;
import com.alibaba.citrus.cr.common.enums.ordercenter.AsyncMessageEventEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.DictionaryTypeEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.OrderCategoryEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.SalesOrderPushStatusEnum;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.mn.order.center.common.SetOrderTag;
import com.alibaba.citrus.cr.mn.order.center.common.util.AssertUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.StopWatchUtils;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.DictionaryVerifyAdapter;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.OrderAtomUpdateRequestToOrderConvert;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.OrderLineAtomUpdateRequestToOrderLineConvert;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.OrderUpdateParamsConvertService;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.middleware.mq.runtime.EpochMessageService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crb2btradecenter.domain.order.dto.QueryByOrderBizIdsRequest;
import com.epoch.app.crb2btradecenter.domain.order.model.Order;
import com.epoch.app.crb2btradecenter.domain.order.service.OrderService;
import com.epoch.app.crb2btradecenter.domain.orderline.dto.DeleteByMainIdRequest;
import com.epoch.app.crb2btradecenter.domain.orderline.dto.LoadListResponse;
import com.epoch.app.crb2btradecenter.domain.orderline.dto.OrderLineLoadListRequest;
import com.epoch.app.crb2btradecenter.domain.orderline.model.OrderLine;
import com.epoch.app.crb2btradecenter.domain.orderline.service.OrderLineService;
import com.epoch.app.crb2btradecenter.enums.OrderStatus;
import com.epoch.app.crb2btradecenter.sdo.OrderLineSDO;
import com.epoch.app.crb2btradecenter.sdo.OrderSDO;
import com.epoch.app.mnordercenter.model.dto.CommonAsyncMessageResponse;
import com.epoch.app.mnordercenter.model.dto.PushOrderInfoToMnSideRequestOrderInfo;
import com.epoch.app.mnordercenter.model.dto.SalesOrderModifyRequest;
import com.epoch.app.mnordercenter.orderbaserequest.OrderAtomUpdateRequest;
import com.epoch.app.mnordercenter.orderbaserequest.OrderAtomUpdateResponse;
import com.epoch.app.mnordercenter.orderbaserequest.OrderLineAtomCreateResponse;
import com.epoch.app.mnordercenter.orderbaserequest.OrderLineAtomUpdateRequest;
import com.epoch.app.mnordercenter.salesorderatom.dto.SapModifyCallbackRequest;
import com.google.common.collect.Lists;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.alibaba.citrus.cr.common.constant.OrderFeaturesKey.*;

/**
 * Chen.mu
 * 2023/5/11
 **/
public abstract class AbstractOrderAtomUpdateService implements OrderAtomUpdateService {
    private static final Log log = Log.getLogger(AbstractOrderAtomUpdateService.class);

    @Resource
    private OrderQueryServiceRepository orderQueryServiceRepository;
    @Resource
    private OrderWriteRepository orderWriteRepository;
    @Resource
    private OrderLineWriteRepository orderLineWriteRepository;
    @Resource
    private SendMsgService sendMsgService;
    @Resource
    private OrderService orderService;
    @Resource
    private OrderLineService orderLineService;
    @Resource
    private OrderAtomUpdateRequestToOrderConvert orderAtomUpdateRequestToOrderConvert;
    @Resource
    private OrderLineAtomUpdateRequestToOrderLineConvert orderLineAtomUpdateRequestToOrderLineConvert;
    @Resource
    private OrderUpdateParamsConvertService orderUpdateParamsConvertService;
    @Resource
    private DictionaryVerifyAdapter dictionaryVerifyAdapter;
    @Resource
    private EpochMessageService messageService;
    private static final String SALE_ORDER_MODIFY_RETRY_MESSAGE = "sales_order_modify_retry_message";
    private static final String SALES_MQ_TOPIC = "CR_SALEORDER_V2";
    private static final String SALES_ORDER_MODIFY_RETRY_TAG = "SalesOrderModifyRetry";
    /**
     * 更新方案：
     * 1.传入的更新(A)对象要传所有明细
     * 2.捞出数据库该订单所有明细(B)
     * 3.根据行号对比明细， 校对AB匹配的明细行，校验可否更新， 不可更新，整单失败
     * 4.A有B无-新增，  A有B有-更新   A无B有-物理删除
     * 5.操作子单
     * 6.更新主单
     */
    @Override
    @EpochTransactional(appCode = "mn_order_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    public void submitSaveTransactional(OrderAtomUpdateRequest request, OrderAtomUpdateResponse response) {
        log.info("AbstractOrderBizUpdateService#submitSaveTransactional request={} response={}", JSON.toJSONString(request), JSON.toJSONString(response));

        //查询订单信息
        StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "queryOrder");
        response.setSalesOrderNo(request.getSalesOrderNo());
        Order dbOrder = queryOrder(request, request.getSalesOrderNo());
        StopWatchUtils.stop();
        if (Objects.isNull(dbOrder)) {
            response.setErrorCode("OC-01-001-01-16-016");
            response.setMessage("订单不存在");
            return;
        }
        //查询订单明细
        StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "queryOrderLines");
        List<OrderLine> dbOderLines = queryOrderLines(dbOrder.getId());
        StopWatchUtils.stop();

        //校验订单状态
        StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "checkOrder");
        boolean isSuccess = checkOrder(dbOrder, dbOderLines, request, response);
        StopWatchUtils.stop();
        if (!isSuccess) {
            // 校验失败直接返回
            return;
        }
        //拼接外部单号，发sap要用
        request.setOutOrderNo(dbOrder.getOuterOrderId());

        StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "convert");
        List<OrderLine> orderLinesForAdd = new ArrayList<>();
        List<OrderLine> orderLinesForUpdate = new ArrayList<>();
        AtomicInteger currentMaxLineNum = new AtomicInteger();
        // 缓存订单行
        Map<String, OrderLine> orderLineSDOMap = new HashMap<>();
        for (OrderLine dbOrderLine : dbOderLines) {
            if (StringUtils.isNotBlank(dbOrderLine.getSerialNumber())) {
                currentMaxLineNum.set(Math.max(Integer.parseInt(dbOrderLine.getSerialNumber()), currentMaxLineNum.get()));
            }
            orderLineSDOMap.put(dbOrderLine.getSerialNumber(), dbOrderLine);
        }

        Date now = new Date();
        AtomicReference<String> warehouseCodeForMainOrderSet = new AtomicReference<>("");
        request.getOrderDetails().forEach(orderLineRequest -> {
            // 新增明细行
            if (StringUtils.isBlank(orderLineRequest.getLineNum())) {
                currentMaxLineNum.set(currentMaxLineNum.get() + 10);
                //构造新增明细数据对象
                OrderLine dbOrderLine = orderLineAtomUpdateRequestToOrderLineConvert.convert(orderLineRequest);
                dbOrderLine.setSerialNumber(String.valueOf(currentMaxLineNum.get()));
                dbOrderLine.setMainOrderId(String.valueOf(dbOrder.getId()));
                dbOrderLine.setMainOrderBizId(dbOrder.getOrderBizId());
                dbOrderLine.setOrderLineTag(dbOrder.getOrderTag());
                if (SetOrderTag.NORMAL.equals(dbOrder.getOrderTag())) {
                    dbOrderLine.setReceiveWarehouseName(null);
                    dbOrderLine.setReceiveWarehouseOutCode(null);
                    dbOrderLine.setReceiveFactoryCode(null);
                    dbOrderLine.setReceiveStockCode(null);
                    dbOrderLine.setReceiveFactoryCode(null);
                }
                dbOrderLine.setStatus(Optional.ofNullable(dbOrderLine.getStatus()).orElse(OrderStatus.BEFORE_SUBMIT.getCode()));
                dbOrderLine.setGmtCreate(now);
                dbOrderLine.setSyncVersion(0);
                dbOrderLine.setModifierId(request.getModifierCode());
                dbOrderLine.setModifierName(request.getModifierName());
                if (OrderCategoryEnum.STOCK.getCode().equals(request.getOrderCategoryCode())) {
                    dbOrderLine.setRelationLineNo(String.valueOf(currentMaxLineNum.get()));
                }
                orderLinesForAdd.add(dbOrderLine);
                if (StringUtils.isNotBlank(dbOrderLine.getShippingWarehouseCode())) {
                    warehouseCodeForMainOrderSet.set(dbOrderLine.getShippingWarehouseCode());
                }
            }

            // 更新明细行
            if (StringUtils.isNotBlank(orderLineRequest.getLineNum())) {
                OrderLine dbOrderLine = orderLineSDOMap.get(orderLineRequest.getLineNum());
                //构造更新明细数据对象
                boolean hasInfoChange = orderLineAtomUpdateRequestToOrderLineConvert.convert(dbOrderLine, orderLineRequest, dbOrder.getOrderCategoryCode());
                if (hasInfoChange) {
                    //如果只传了明细行号，没内容变更，则不修改修改人和时间
                    dbOrderLine.setModifierName(request.getModifierName());
                    dbOrderLine.setModifierId(request.getModifierCode());
                    dbOrderLine.setGmtModified(new Date());
                }
                orderLinesForUpdate.add(dbOrderLine);
                if (StringUtils.isNotBlank(dbOrderLine.getShippingWarehouseCode())) {
                    warehouseCodeForMainOrderSet.set(dbOrderLine.getShippingWarehouseCode());
                }
            }
        });
        log.info("AbstractOrderBizUpdateService#convert orderLinesForAdd={}", JSON.toJSONString(orderLinesForAdd));
        log.info("AbstractOrderBizUpdateService#convert orderLinesForUpdate={}", JSON.toJSONString(orderLinesForUpdate));
        StopWatchUtils.stop();

        // 待提交或者(退货订单)待推送状态：删除原明细，重新插入明细数据
        if (OrderStatus.BEFORE_SUBMIT.getCode().equals(dbOrder.getStatus())
                || (SetOrderTag.RETURN.equals(dbOrder.getOrderTag()) && OrderStatus.STAY_PUSH.getCode().equals(dbOrder.getStatus()))) {
            // 删除修改前的明细
            StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "deleteByIds");
            DeleteByMainIdRequest deleteByMainIdRequest = new DeleteByMainIdRequest();
            deleteByMainIdRequest.setMainId(dbOrder.getId());
            orderLineService.deleteByMainId(deleteByMainIdRequest);
            StopWatchUtils.stop();

            // 保存新增/修改的明细
            StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "createOrderLine");
            orderLinesForAdd.forEach(x -> orderLineService.createOrderLine(x));
            orderLinesForUpdate.forEach(x -> orderLineService.createOrderLine(x));
            StopWatchUtils.stop();

            //回填主单要更新的字段数据
            orderAtomUpdateRequestToOrderConvert.convert(dbOrder, request, warehouseCodeForMainOrderSet.get());
        }

        // 已提交及后续状态，先把更新信息存在features里，等SAP修改完成后再进行修改操作
        if (OrderStatus.BEFORE_DELIVERY.getCode().equals(dbOrder.getStatus())
                || OrderStatus.PARTIAL_DELIVER.getCode().equals(dbOrder.getStatus())
                || OrderStatus.WAIT_RECEIVING.getCode().equals(dbOrder.getStatus())
                || OrderStatus.PART_RECEIVING.getCode().equals(dbOrder.getStatus())
                || OrderStatus.WAIT_HANDLE.getCode().equals(dbOrder.getStatus())
                || OrderStatus.PARTIAL_HANDLE.getCode().equals(dbOrder.getStatus())) {

            StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "sendMsgToSAP");
            // 已提交到SAP的订单，需要等SAP修改成功后再进行真实修改操作，在features里增加修改标updateLock，防止重复提交修改
            JSONObject features = JSON.parseObject(Optional.ofNullable(dbOrder.getFeatures()).orElse(""));
            features.put("updateLock", "true");
            features.put("updateJson", JSON.toJSONString(request));
            dbOrder.setFeatures(features.toJSONString());
            // 发送消息通知SAP进行修改
            sendMsgService.sendMsgToSAP(JSON.toJSONString(Collections.singletonList(request)));
            StopWatchUtils.stop();
        }

        // 先更新修改人信息，防止SAP回调时丢失修改人信息
        dbOrder.setModifier(request.getModifierCode());
        dbOrder.setModifierCode(request.getModifierCode());
        dbOrder.setModifierName(request.getModifierName());
        dbOrder.setModifierName2(request.getModifierName());
        dbOrder.setGmtModified(now);

        StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "updateOrder");
        orderService.updateOrder(dbOrder);
        StopWatchUtils.stop();

        // 构建新建子单行号、来源单号 response
        List<OrderLineAtomCreateResponse> orderDetailList = new ArrayList<>();
        orderLinesForAdd.forEach(orderLine -> {
            orderDetailList.add(OrderLineAtomCreateResponse.builder().lineNum(orderLine.getSerialNumber()).sourceLineNum(orderLine.getSourceLineNum()).build());
        });
        response.setOrderDetails(orderDetailList);

        // F1-B-b订单同步修改F-B订单信息，目前只有待提交状态才允许修改此订单
        if (OrderCategoryEnum.STOCK.getCode().equals(request.getOrderCategoryCode())) {
            List<OrderLine> allOrderLines = new ArrayList<>();
            allOrderLines.addAll(orderLinesForAdd);
            allOrderLines.addAll(orderLinesForUpdate);
            try {
                updateGroupOrder(request, dbOrder, allOrderLines);
            } catch (Exception e) {
                log.error("AbstractOrderBizUpdateService#submitSaveTransactional updateGroupOrder error", e);
            }
        }
    }

    protected Order queryOrder(OrderAtomUpdateRequest request, String salesOrderNo) {
        if (StringUtils.isBlank(salesOrderNo)) {
            log.info("queryOrder salesOrderNo={}",JSON.toJSONString(salesOrderNo));
            return null;
        }
        //查询订单信息
        QueryByOrderBizIdsRequest queryByOrderBizIdsRequest = QueryByOrderBizIdsRequest.builder()
                .fromSys(request.getFromSys())
                .businessType(Integer.valueOf(request.getBusinessType()))
                .businessUnitOutCode(request.getBusinessUnitCode())
                .orderBizIds(Lists.newArrayList(salesOrderNo))
                .limit(1)
                .build();
        Result<List<Order>> ordersResult = orderService.queryByOrderBizIds(queryByOrderBizIdsRequest);
        if (CollectionUtils.isEmpty(ordersResult.getResult())) {
            return null;
        }
        return ordersResult.getResult().get(0);
    }

    protected List<OrderLine> queryOrderLines(Long orderId) {
        OrderLineLoadListRequest orderLineLoadListRequest = new OrderLineLoadListRequest();
        orderLineLoadListRequest.setMainOrderId(String.valueOf(orderId));
        orderLineLoadListRequest.setStart(0);
        orderLineLoadListRequest.setLimit(999);
        LoadListResponse loadListResponse = orderLineService.loadList(orderLineLoadListRequest);
        if (Objects.isNull(loadListResponse)) {
            return Lists.newArrayList();
        }
        List<OrderLine> result = loadListResponse.getResult();
        return JSONArray.parseArray(JSONObject.toJSONString(result), OrderLine.class);
    }

    /**
     * 校验订单
     */
    private boolean checkOrder(Order order, List<OrderLine> orderLines, OrderAtomUpdateRequest request, OrderAtomUpdateResponse response) {
        // 校验订单状态
        String message = checkOrderStatus(order);
        if (StringUtils.isNotBlank(message)) {
            response.setErrorCode("OC-01-001-01-16-053");
            response.setMessage(message);
            return false;
        }

        // 校验明细信息
        Set<String> dbLineNumList = new HashSet<>();
        Map<String, OrderLine> orderLineMap = new HashMap<>();
        for (OrderLine orderLine : orderLines) {
            dbLineNumList.add(orderLine.getSerialNumber());
            orderLineMap.put(orderLine.getSerialNumber(), orderLine);
        }

        Set<String> requestLineNumList = new HashSet<>();
        for (OrderLineAtomUpdateRequest lineAtomUpdateRequest : request.getOrderDetails()) {
            // 新增明细
            if (StringUtils.isBlank(lineAtomUpdateRequest.getLineNum())) {
                //非【待提交】状态订单，不允许新增行
                if (!OrderStatus.BEFORE_SUBMIT.getCode().equals(order.getStatus())) {
                    response.setErrorCode("OC-01-001-01-16-053");
                    response.setMessage("当前操作与订单可执行操作不匹配");
                    return false;
                }
            }

            // 修改明细
            if (StringUtils.isNotBlank(lineAtomUpdateRequest.getLineNum())) {
                String lineNumInRequest = lineAtomUpdateRequest.getLineNum();
                OrderLine orderLine = orderLineMap.get(lineNumInRequest);
                if (Objects.isNull(orderLine)) {
                    response.setErrorCode("OC-01-001-01-16-017");
                    response.setMessage(ErrorMessage.code("OC-01-001-01-16-017", lineNumInRequest).getDisplayErrorMessage());
                    return false;
                }

                // 校验订单行
                message = checkOrderLineStatus(orderLine);
                if (StringUtils.isNotBlank(message)) {
                    response.setErrorCode("OC-01-001-01-16-053");
                    response.setMessage(message);
                    return false;
                }

                requestLineNumList.add(lineNumInRequest);
                //拼接外部单号，发sap要用
                lineAtomUpdateRequest.setOutLineNum(orderLine.getOuterOrderLineId());
            }
        }

        //非【待提交】状态订单，校验入参的行号和数据库里的行号是否都一致
        if (!OrderStatus.BEFORE_SUBMIT.getCode().equals(order.getStatus())) {
            if (!dbLineNumList.containsAll(requestLineNumList) && requestLineNumList.containsAll(dbLineNumList)) {
                //如果临时map与数据库的明细数相同，则不存在删除项
                response.setErrorCode("OC-01-001-01-16-053");
                response.setMessage("当前操作与订单可执行操作不匹配");
                return false;
            }
        }
        return true;
    }

    /**
     * 校验订单状态
     */
    private String checkOrderStatus(Order order) {
        List<Integer> canUpdateStatus = Lists.newArrayList(
                OrderStatus.BEFORE_SUBMIT.getCode(),
                OrderStatus.BEFORE_DELIVERY.getCode(),
                OrderStatus.PARTIAL_DELIVER.getCode(),
                OrderStatus.STAY_PUSH.getCode(),
                OrderStatus.PARTIAL_HANDLE.getCode(),
                OrderStatus.WAIT_HANDLE.getCode(),
                OrderStatus.WAIT_RECEIVING.getCode(),
                OrderStatus.PART_RECEIVING.getCode()
        );
        String message = ""; // 错误原因
        // 校验订单状态
        if (!canUpdateStatus.contains(order.getStatus())) {
            message = ErrorMessage.code("OC-01-001-01-16-053").getDisplayErrorMessage();
            return message;
        }

        return message;
    }

    /**
     * 校验订单行状态
     */
    private String checkOrderLineStatus(OrderLine orderLine) {
        List<Integer> cantUpdateStatus = Lists.newArrayList(
                OrderStatus.BEFORE_SUBMIT.getCode(),
                OrderStatus.BEFORE_DELIVERY.getCode(),
                OrderStatus.PARTIAL_DELIVER.getCode(),
                OrderStatus.STAY_PUSH.getCode(),
                OrderStatus.PARTIAL_HANDLE.getCode(),
                OrderStatus.WAIT_HANDLE.getCode(),
                OrderStatus.WAIT_RECEIVING.getCode(),
                OrderStatus.PART_RECEIVING.getCode()
        );
        String message = ""; // 错误原因
        // 校验订单状态
        if (!cantUpdateStatus.contains(orderLine.getStatus())) {
            message = ErrorMessage.code("OC-01-001-01-16-053").getDisplayErrorMessage();
            return message;
        }

        return message;
    }

    @Override
    public void compareAndSpiltDetail(OrderAtomUpdateRequest request) {
        StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "compareAndSpiltDetail");
        AssertUtils.isTrue(StringUtils.isBlank(request.getFromSys()), "OC-01-001-01-15-001", "来源系统编码");
        AssertUtils.isTrue(StringUtils.isBlank(request.getBusinessType()), "OC-01-001-01-15-001", "业态编码");
        AssertUtils.isTrue(StringUtils.isBlank(request.getBusinessUnitCode()), "OC-01-001-01-15-001", "业务单元编码");
        AssertUtils.isTrue(StringUtils.isBlank(request.getSalesOrderNo()), "OC-01-001-01-15-001", "换货订单号");

        AssertUtils.lengthCheck(request.getFromSys(), 50, true, "OC-01-001-01-15-004", "来源系统编码");
        AssertUtils.lengthCheck(request.getBusinessType(), 10, true, "OC-01-001-01-15-004", "业态编码");
        AssertUtils.lengthCheck(request.getBusinessUnitCode(), 50, true, "OC-01-001-01-15-004", "业务单元编码");
        AssertUtils.lengthCheck(request.getSalesOrderNo(), 50, true, "OC-01-001-01-15-004", "换货订单单号");

        // 枚举值校验
        dictionaryVerifyAdapter.verifyDictionary(DictionaryTypeEnum.FROM_SYS.getCode(), request.getFromSys(), new FunctionException("OC-01-001-01-15-006", "来源系统编码"));
        dictionaryVerifyAdapter.verifyDictionary(DictionaryTypeEnum.BUSINESS_TYPE.getCode(), request.getBusinessType(), new FunctionException("OC-01-001-01-15-006", "业态编码"));
//        dictionaryVerifyAdapter.verifyDictionary(DictionaryTypeEnum.BUSINESS_UNIT_CODE.getCode(), request.getBusinessUnitCode(), new FunctionException("OC-01-001-01-15-006", "业务单元编码"));

        request = orderUpdateParamsConvertService.convert(request, getOrderTag());
        // 传参有内部行号走更新，没有按新增算
        for (OrderLineAtomUpdateRequest orderLineRequest : request.getOrderDetails()) {
            if (StringUtils.isBlank(orderLineRequest.getLineNum())) {
//                orderLineRequest.setUpdateTag(ADD_DETAIL_KEY);
            } else {
                orderLineRequest.setProductCode("");
//                orderLineRequest.setUpdateTag(UPDATE_DETAIL_KEY);
            }
        }
        StopWatchUtils.stop();
    }

    private void updateGroupOrder(OrderAtomUpdateRequest request, Order dbOrder, List<OrderLine> orderLines) {
        // 修改F-B订单数据
        StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "queryGroupOrder");
        Order dbGroupOrder = queryOrder(request, dbOrder.getRelationNo());
        StopWatchUtils.stop();

        if (Objects.nonNull(dbGroupOrder)) {
            dbGroupOrder.setTransportModeCode(dbOrder.getTransportModeCode());
            dbGroupOrder.setTransportModeName(dbOrder.getTransportModeName());
            dbGroupOrder.setCustomerExpectDate(dbOrder.getCustomerExpectDate());
            dbGroupOrder.setFulfillmentPriority(dbOrder.getFulfillmentPriority());
            dbGroupOrder.setOrderBizTag(dbOrder.getOrderBizTag());
            dbGroupOrder.setCreateReason(dbOrder.getCreateReason());
            dbGroupOrder.setCreateReasonName(dbOrder.getCreateReasonName());
            dbGroupOrder.setModifier(dbOrder.getModifier());
            dbGroupOrder.setModifierCode(dbOrder.getModifierCode());
            dbGroupOrder.setModifierName(dbOrder.getModifierName());
            dbGroupOrder.setModifierName2(dbOrder.getModifierName2());
            dbGroupOrder.setGmtModified(dbOrder.getGmtModified());
            dbGroupOrder.setRemark(dbOrder.getRemark());
            dbGroupOrder.setBizFeatures(dbOrder.getBizFeatures());

            StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "updateGroupOrder");
            orderService.updateOrder(dbGroupOrder);
            StopWatchUtils.stop();

            // 修改F-B订单明细数据
            // 删除修改前的明细
            StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "deleteGroupByIds");
            DeleteByMainIdRequest deleteByMainIdRequest = new DeleteByMainIdRequest();
            deleteByMainIdRequest.setMainId(dbGroupOrder.getId());
            orderLineService.deleteByMainId(deleteByMainIdRequest);
            StopWatchUtils.stop();

            // 保存新增/修改的明细
            StopWatchUtils.start(CORE_STOP_WATCH_SEQ, "createGroupOrderLine");
            orderLines.forEach(x -> {
                x.setId(null);
                x.setMainId(dbGroupOrder.getId());
                x.setMainOrderId(String.valueOf(dbGroupOrder.getId()));
                x.setMainOrderBizId(dbGroupOrder.getOrderBizId());
                x.setShouldPayFee(String.valueOf(Integer.valueOf(x.getUnitPrice()) * x.getQuantity()));

                JSONObject features = JSON.parseObject(Optional.ofNullable(x.getFeatures()).orElse(""));
                features.remove(KA_AREA);
                features.remove(KA_SYSTEM);
                features.remove(SOURCE_UNIT);
                features.remove(SOURCE_PRICE);
                features.remove(SOURCE_QUANTITY);
                x.setFeatures(features.toJSONString());

                orderLineService.createOrderLine(x);
            });
            StopWatchUtils.stop();
        } else {
            log.error("AbstractOrderBizUpdateService#submitSaveTransactional 集团订单查询失败");
        }
    }

    /**
     * 调用SAP修改接口后回调逻辑
     */
    @Override
    public void modifyCallback(SapModifyCallbackRequest sapModifyCallbackRequest) {
        if (sapModifyCallbackRequest == null || CollectionUtils.isEmpty(sapModifyCallbackRequest.getData())) {
            log.info("OrderAtomUpdateService_SapModifyCallback_request_is_null");
            return;
        }

        // 发送kafka消息要传的内容
        String fromSys = "";
        String businessUnitCode = "";

        List<String> failOrderBizIds = new ArrayList<>();
        //修改订单，释放订单编辑锁
        for (SalesOrderModifyRequest modifyRequest : sapModifyCallbackRequest.getData()) {
            OrderSDO order = orderQueryServiceRepository.queryByOuterOrderId(modifyRequest.getVBELN());
            if (Objects.isNull(order)) {
                log.info("OrderAtomUpdateService_SapModifyCallback_orderid_not_exist,outerOrderId={}", modifyRequest.getVBELN());
                continue;
            }

            if (StringUtils.isBlank(fromSys)) {
                fromSys = order.getFromSys();
            }
            if (StringUtils.isBlank(businessUnitCode)) {
                businessUnitCode = order.getBusinessUnitOutCode();
            }

            Map<String, String> orderFeatures = MapUtils.isNotEmpty(order.getFeatures()) ? order.getFeatures() : new HashMap<>();
            //修改成功
            if ("S".equals(modifyRequest.getFLAG())) {
                if (orderFeatures.get("updateJson") == null) {
                    log.info("OrderAtomUpdateService_SapModifyCallback_reqSapData_is_null,outerOrderId={}", modifyRequest.getVBELN());
                    continue;
                }
                OrderAtomUpdateRequest batchUpdateRequest = JSON.parseObject(orderFeatures.get("updateJson"), OrderAtomUpdateRequest.class);
                if (StringUtils.isNotBlank(batchUpdateRequest.getDeliveryMethodCode())) {
                    order.setTransportModeCode(batchUpdateRequest.getDeliveryMethodCode());
                }
                if (StringUtils.isNotBlank(batchUpdateRequest.getDeliveryMethodName())) {
                    order.setTransportModeName(batchUpdateRequest.getDeliveryMethodName());
                }
                if (StringUtils.isNotBlank(batchUpdateRequest.getOrderReasonCode())) {
                    order.setCreateReason(batchUpdateRequest.getOrderReasonCode());
                }
                if (StringUtils.isNotBlank(batchUpdateRequest.getOrderReasonName())) {
                    order.setCreateReasonName(batchUpdateRequest.getOrderReasonName());
                }
                if (StringUtils.isNotBlank(batchUpdateRequest.getCostCenterCode())) {
                    order.setCostCenter(batchUpdateRequest.getCostCenterCode());
                }
                if (StringUtils.isNotBlank(batchUpdateRequest.getCostCenterName())) {
                    order.setCostCenterName(batchUpdateRequest.getCostCenterName());
                }
                if (StringUtils.isNotBlank(batchUpdateRequest.getExpectedDeliveryDate())) {
                    order.setCustomerExpectDate(DateUtils.parse(batchUpdateRequest.getExpectedDeliveryDate()));
                }
                if (StringUtils.isNotBlank(batchUpdateRequest.getNote())) {
                    order.setRemark(batchUpdateRequest.getNote());
                }
                order.setModifierCode(batchUpdateRequest.getModifierCode());
                order.setModifierName(batchUpdateRequest.getModifierName());
                order.setModifierName2(batchUpdateRequest.getModifierName());
                orderFeatures.put("updateLock", "false");
                order.setFeatures(orderFeatures);
                orderWriteRepository.updateOrder(order);

                Map<String, OrderLineSDO> orderLineMap = order.getOrderLineSDOS().stream().collect(Collectors.toMap(OrderLineSDO::getOuterOrderLineId, Function.identity(), (v1, v2) -> v1));
                for (OrderLineAtomUpdateRequest request : batchUpdateRequest.getOrderDetails()) {
                    OrderLineSDO orderLineSDO = orderLineMap.get(request.getOutLineNum());
                    if (StringUtils.isBlank(request.getNote())) {
                        continue;
                    }
                    orderLineSDO.setRemark(request.getNote());
                    orderLineWriteRepository.modifyOrderLine(orderLineSDO);
                }
            } else {
                //修改失败
                //对于由于并发问题导致sap反馈正在处理的情况发重试消息
                if(modifyRequest.getMESSAGE().contains("正在处理")){
                    Boolean batchSendResp = messageService.sendMessage(SALE_ORDER_MODIFY_RETRY_MESSAGE, SALES_MQ_TOPIC, SALES_ORDER_MODIFY_RETRY_TAG, modifyRequest.getVBELN());
                    log.info("sales order update retry message={},resp={}",JSON.toJSONString(modifyRequest.getVBELN()),batchSendResp);
                }

                orderFeatures.put("updateLock", "false");
                order.setFeatures(orderFeatures);
                orderWriteRepository.updateOrder(order);

                failOrderBizIds.add(modifyRequest.getVBELN());
            }
        }

        //SAP修改失败，推送牛要客，SAP修改成功处理，交给SAP015集成接口
        if (CollectionUtils.isNotEmpty(failOrderBizIds)) {
            List<PushOrderInfoToMnSideRequestOrderInfo> pushOrderInfoList = failOrderBizIds.stream().map(id -> {
                PushOrderInfoToMnSideRequestOrderInfo pushOrderInfo = new PushOrderInfoToMnSideRequestOrderInfo();
                pushOrderInfo.setSalesOrderNo(id);
                pushOrderInfo.setOrderStatus(SalesOrderPushStatusEnum.FAIL_UPDATE.getOrderStatusCode());
                return pushOrderInfo;
            }).collect(Collectors.toList());

            AsyncMessageEventEnum event;
            switch (getOrderTag()) {
                case SetOrderTag.RETURN:
                    event = AsyncMessageEventEnum.RETURN_ORDER_UPDATE;
                    break;
                case SetOrderTag.EXCHANGE:
                    event = AsyncMessageEventEnum.EXCHANGE_ORDER_UPDATE;
                    break;
                default:
                    event = AsyncMessageEventEnum.SALES_ORDER_UPDATE;
                    break;
            }

            CommonAsyncMessageResponse commonAsyncMessageResponse = new CommonAsyncMessageResponse();
            commonAsyncMessageResponse.setEventCode(event.getValue());
            commonAsyncMessageResponse.setEventName(event.getLabel());
            commonAsyncMessageResponse.setEventTime(String.valueOf(new Date().getTime()));
            commonAsyncMessageResponse.setFromSys(fromSys);
            commonAsyncMessageResponse.setBusinessUnitCode(businessUnitCode);
            commonAsyncMessageResponse.setData(pushOrderInfoList);
            sendMsgService.sendMsgToSendKafka(commonAsyncMessageResponse);
            log.info("AbstractOrderAtomUpdateService#modifyCallback sendMsgToSendKafka message={}", commonAsyncMessageResponse);
        }
    }
}
